using System;
using System.Data;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace Glpt.Common
{
    /// <summary>
    /// 校验状态改变的事件委托
    /// </summary>
    /// <param name="sender">对象</param>
    public delegate void ValidateStateChangedEventHandler(GJTextBox sender);

    /// <summary>
    /// 自定义的TextBox组件
    /// </summary>
    public class GJTextBox : TextBox
    {
        private bool Eventable = true;  //是否启用事件
        private string regularexpressions = "";
        private MaskedTextBox masktxtbox = new MaskedTextBox();
        private string defaultValue = "";
        private string oldvalue = "";
        private bool allowNull = true;
        private bool allowNumber = true;
        private bool allowDot = true;
        private bool allowLetter = true;
        private bool allowSignChar = true;
        private bool hasValidate = false;//是否校验过
        private bool validate_state = true;
        private ToolTip tooltip = null;
        /// <summary>
        /// 备选数据源
        /// </summary>
        public DataView DataSource = null;
        /// <summary>
        /// 校验状态改变的事件
        /// </summary>
        public event ValidateStateChangedEventHandler ValidateStateChanged;
        /// <summary>
        /// 校验状态改变的方法
        /// </summary>
        /// <param name="sender">对象</param>
        protected virtual void OnValidateStateChanged(GJTextBox sender)
        {
        }

        /// <summary>
        /// 初始化类的新实例
        /// </summary>
        public GJTextBox()
            : base()
        {
            ValidateStateChanged += new ValidateStateChangedEventHandler(OnValidateStateChanged);
        }

        /// <summary>
        /// 获取或设置正规表达式
        /// </summary>
        public string RegularExpressions
        {
            get
            {
                return regularexpressions;
            }
            set
            {
                regularexpressions = value;
            }
        }

        /// <summary>
        /// 获取或设置用于验证用户输入的数据的数据类型。
        /// </summary>
        public Type ValidatingType
        {
            get
            {
                return masktxtbox.ValidatingType;
            }
            set
            {
                masktxtbox.ValidatingType = value;
            }
        }

        /// <summary>
        /// 将用户输入字符串转换为验证类型的一个实例。
        /// </summary>
        /// <returns>如果成功，则为由 ValidatingType 属性指定的类型的 System.Object；否则将返回 null 以指示转换失败。</returns>
        public object ValidateText()
        {
            masktxtbox.Text = this.Text;
            return masktxtbox.ValidateText();
        }

        /// <summary>
        /// 获取或设置是否允许为空
        /// </summary>
        public bool AllowNull
        {
            get
            {
                return allowNull;
            }
            set
            {
                allowNull = value;
            }
        }

        /// <summary>
        /// 获取或设置是否可以输入数字
        /// </summary>
        public bool AllowNumber
        {
            get
            {
                return allowNumber;
            }
            set
            {
                allowNumber = value;
            }
        }

        /// <summary>
        /// 获取或设置是否可以输入小数点
        /// </summary>
        public bool AllowDot
        {
            get
            {
                return allowDot;
            }
            set
            {
                allowDot = value;
            }
        }

        /// <summary>
        /// 获取或设置是否可以输入字母
        /// </summary>
        public bool AllowLetter
        {
            get
            {
                return allowLetter;
            }
            set
            {
                allowLetter = value;
            }
        }

        /// <summary>
        /// 获取或设置是否可以输入符号字符
        /// </summary>
        public bool AllowSignChar
        {
            get
            {
                return allowSignChar;
            }
            set
            {
                allowSignChar = value;
            }
        }

        /// <summary>
        /// 获取或设置缺省值
        /// </summary>
        public string DefaultValue
        {
            get
            {
                return defaultValue;
            }
            set
            {
                defaultValue = value;
                if (this.TextLength == 0)
                    this.Text = defaultValue;
            }
        }

        /// <summary>
        /// 获取或设置校验是否成功
        /// </summary>
        public bool ValidateState
        {
            get
            {
                if (!hasValidate)
                {
                    hasValidate = true;
                    if (allowNull && this.Text.Length == 0)
                        ValidateState = true;
                    else if (!allowNull && this.Text.Length == 0)
                        ValidateState = false;
                    else if (RegularExpressions.Length > 0)
                        ValidateState = Regex.IsMatch(this.Text, RegularExpressions, RegexOptions.None);
                    else if (this.ValidatingType != null)
                    {
                        object obj = this.ValidateText();
                        ValidateState = (obj != null);
                    }
                    else
                        ValidateState = true;
                }
                return validate_state;
            }
            set
            {
                if (validate_state != value)
                {
                    validate_state = value;
                    ValidateStateChanged(this);
                }
            }
        }

        /// <summary>
        /// 显示提示信息
        /// </summary>
        /// <param name="tip">提示信息</param>
        public void ShowTip(string tip)
        {
            if (tooltip == null) tooltip = new ToolTip();
            tooltip.SetToolTip(this, tip);
        }

        /// <summary>
        /// 根据校验状态改变颜色
        /// </summary>
        public void ValidateChangeColor()
        {
            if (ValidateState)
                this.BackColor = SystemColors.Window;
            else
                this.BackColor = SystemColors.Info;
        }

        /// <summary>
        /// 引发 System.Windows.Forms.Control.DoubleClick 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.EventArgs。</param>
        protected override void OnDoubleClick(EventArgs e)
        {
            if (DataSource != null)
            {
                FrmCombSelectDialog frm = new FrmCombSelectDialog();
                frm.DataBind(DataSource);
                frm.SelectedValue = this.Text;
                frm.TextControl = this;
                frm.Location = this.PointToScreen(new Point(-2, -2));
                frm.Width = this.Width + 20;
                frm.Show();
            }
            base.OnDoubleClick(e);
        }

        /// <summary>
        /// 引发 System.Windows.Forms.Control.TextChanged 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.EventArgs。</param>
        protected override void OnTextChanged(EventArgs e)
        {
            if (!Eventable) return;
            if (defaultValue.Length > 0)
            {
                if (this.Text.Length == 0)
                {
                    Eventable = false;
                    this.Text = defaultValue;
                    Eventable = true;
                }
                else if (defaultValue.Equals("0") && this.ValidatingType != null && (this.ValidatingType.Equals(typeof(int)) || this.ValidatingType.Equals(typeof(long)) || this.ValidatingType.Equals(typeof(short)) || this.ValidatingType.Equals(typeof(double)) || this.ValidatingType.Equals(typeof(float))))
                {
                    if (oldvalue.Equals("0") && !this.Text.StartsWith("0.") && this.Text.Length > defaultValue.Length)
                    {
                        Eventable = false;
                        this.Text = this.Text.Replace("0", "");
                        Eventable = true;
                        this.SelectionStart = this.TextLength;
                    }
                }
            }
            oldvalue = this.Text;
            hasValidate = false;
            ValidateChangeColor();
            base.OnTextChanged(e);
        }

        /// <summary>
        /// 引发 System.Windows.Forms.Control.KeyPress 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 System.EventArgs。</param>
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);
            if (e.KeyChar != (char)8 && e.KeyChar != (char)3 && e.KeyChar != (char)22 && e.KeyChar != (char)24)  //允许输入回退键,CTRL+C,CTRL+V,CTRL+X
            {
                if (!allowNumber)
                {
                    if (e.KeyChar >= '0' && e.KeyChar <= '9')
                    {
                        e.Handled = true;
                        return;
                    }
                }
                if (!allowDot)
                {
                    if (e.KeyChar == '.')
                    {
                        e.Handled = true;
                        return;
                    }
                }
                if (!allowLetter)
                {
                    if ((e.KeyChar >= 'a' && e.KeyChar <= 'z') || (e.KeyChar >= 'A' && e.KeyChar <= 'Z'))
                    {
                        e.Handled = true;
                        return;
                    }
                }
                if (!allowSignChar)
                {
                    if (e.KeyChar != '.' && !(e.KeyChar >= '0' && e.KeyChar <= '9' || allowNumber && e.KeyChar == '-') && !((e.KeyChar >= 'a' && e.KeyChar <= 'z') || (e.KeyChar >= 'A' && e.KeyChar <= 'Z')))
                    {
                        e.Handled = true;
                        return;
                    }
                }
            }
        }
    }
}
